﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using AutoMapper;
using AzureDiagMon.Common.Interfaces;
using Ninject;
using Ninject.Modules;
using Ninject.Parameters;

namespace AzureDiagMon.Common
{
    public static class IoC
    {
        private readonly static IKernel Kernel =
            new StandardKernel(new NinjectSettings()
            {
#if !WINDOWS_PHONE
                InjectNonPublic = true
#endif
            });

        internal static void SetupAutomapper(Assembly a)
        {
            var creators = a.GetTypes().Where(f => typeof(IMapCreator).IsAssignableFrom(f));
            foreach (var creatorType in creators)
            {
                var creator = Activator.CreateInstance(creatorType) as IMapCreator;
                if (creator != null)
                    creator.CreateMap(Mapper.Configuration);
            }
        }

        public static void Inject(object o)
        {
            Kernel.Inject(o);
        }

        public static T Get<T>()
        {
            return Kernel.Get<T>();
        }

        public static T Get<T>(string name, params IParameter[] parameters)
        {
            return Kernel.Get<T>(name, parameters);
        }

        public static T Get<T>(IEnumerable<string> names) where T : class
        {
            foreach (var name in names)
            {
                try
                {
                    var result = Kernel.Get<T>(name);
                    return result;
                }
                catch (Exception ex)
                {
                    var bindings = Kernel.GetBindings(typeof(T));

                    //Debug.WriteLine(ex);
                    Debug.WriteLine(string.Format("Ninject failed: {0} ({1}): {2}", name, typeof(T), ex));
                    foreach (var binding in bindings)
                    {
                        Debug.WriteLine(binding.BindingConfiguration.Metadata.Name);
                    }
                }
            }
            return (T)null;
        }

        public static void RegisterModule(Type type)
        {
            RegisterModule(type.Assembly);
        }

        public static void RegisterModule(Assembly assembly)
        {
            //TODO: Implment WP7 call
#if !WINDOWS_PHONE
            Kernel.Load((IEnumerable<Assembly>)new[] { assembly });
#endif
            SetupAutomapper(assembly);
        }
    }
}
